﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Skynet
{
    
    public partial class ucDom : UserControl
    {
        private Rectangle dragBoxFromMouseDown;
        private int rowIndexFromMouseDown;
        private int rowIndexOfItemUnderMouseToDrop;
        public bool qqqq=false; 
        private bool a = true;
        public frmSkynet pf;
        public Domains domains = new Domains();
        
        public String OldDom;
        public String OldValue;
        public bool CodeChange;
        public ucDom()
        {
            InitializeComponent();

            // ?
            if (this.Tag != null)
            {


                domains = ((frmSkynet) (this.Tag)).domains;
            }
            foreach (Domain domain in domains.domList)
                {
                    dgvDomian.Rows.Add(domain.Row);
                }
                foreach (Value value in domains.valList)
                {
                    if (value.domainRow==domains.domList[0].Row)
                    {
                        dgvValue.Rows.Add(value.Row);
                    }
                }
        }

    

        private void dgvDomian_CellValidated(object sender, DataGridViewCellEventArgs e)
        {

            if (dgvDomian[e.ColumnIndex, e.RowIndex].Value == null && OldDom != null)
            {
                dgvDomian.CurrentCell.Value = OldDom;
                tsslDom.BackColor = Color.Blue;
                tsslDom.Text = "для удаления ячейки выделите ее и нажмите Del";
            }
            if (dgvDomian[e.ColumnIndex, e.RowIndex].Value != null)
            {
                // проверим на пустые значения
                if (string.IsNullOrWhiteSpace(dgvDomian[e.ColumnIndex, e.RowIndex].Value.ToString()))
                {
                    tsslDom.BackColor = Color.Red;
                    tsslDom.Text = "Пустой домен";
                    dgvDomian.Tag = e.RowIndex;
                    return;
                }
                for (int i = 0; i < ((DataGridView) sender).RowCount - 1; i++)
                {
                    if (((DataGridView) sender)[e.ColumnIndex, e.RowIndex].Value.ToString() ==
                        ((DataGridView) sender)[e.ColumnIndex, i].Value.ToString() && e.RowIndex != i)
                    {
                        tsslDom.BackColor = Color.Red;
                        tsslDom.Text = "Повторяющиеся домены";
                        dgvDomian.Tag = e.RowIndex;
                        return;

                    }
                }
                //если попали сюда значить все нормально
                bool domExist = false; // проверить на существование
                foreach (Domain domain in domains.domList)
                {
                    if (domain.Row == ((DataGridView) sender).Rows[e.RowIndex])
                    {
                        domExist = true;
                    }
                }
                if (!domExist)
                {
                    var domain = new Domain();
                    domain.Row = ((DataGridView) sender).CurrentRow;
                    domains.domList.Add(domain);
                }
            }
        }

        private void dgvDomian_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            if (dgvDomian.Rows[e.RowIndex] != null)
            {
                if (dgvDomian.Rows[e.RowIndex].Cells[0].Value != null)
                {
                    OldDom = dgvDomian.Rows[e.RowIndex].Cells[0].Value.ToString();
                }
                else
                {
                    OldDom = null;
                }
            }
            else
            {
                OldDom = null;
            }        
        }

        private void dgvDomian_Enter(object sender, EventArgs e)
        {
            if (!((DomainsEditor)(this.ParentForm)).ProgramChanging)
            {
                if (!a)
                {
                    dgvValue.ReadOnly = true;
                    dgvValue.Rows.Clear();
                }
                else
                {
                    a = false;
                }
              
            }
        }

        private void dgvDomian_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                if (dgvDomian.CurrentCell.Value != null)
                {
                    var a = pf.diagram.Nodes;
                    foreach (IconNode node in a)
                    {
                        if (node.domain==dgvDomian.CurrentRow.Cells[0].Value.ToString())
                        {
                            tsslDom.Text = "Данный домен используется";
                            dgvDomian.AllowUserToDeleteRows = false;
                        }
                    }

                }
            }
        }

        private void dgvDomian_MouseEnter(object sender, EventArgs e)
        {
            tsslDom.BackColor = Color.White;
            tsslDom.Text = "Введите в ячейку имя домена";
        }

        private void dgvDomian_SelectionChanged(object sender, EventArgs e)
        {
            CodeChange = true;
            dgvValue.Rows.Clear();
            if (dgvDomian.CurrentCell.Value != null)
            {
                // загружаем значения выделенного домена
                foreach (Value value in domains.valList)
                {

                    if (value.domainRow == dgvDomian.CurrentRow)
                    {
                        dgvValue.Rows.Add(value.Row);
                    }
                }
            }
            CodeChange = false;
            select_error();
        }
        private void select_error()
        {
            if (dgvDomian.Tag != null)
            {
                int temp = (int)dgvDomian.Tag;
                dgvDomian.Tag = null;
                dgvDomian.ClearSelection();
                dgvDomian.CurrentCell = dgvDomian[0, temp];
                dgvDomian.Rows[temp].Selected = true;
                dgvDomian.BeginEdit(true);
            }
        }

        private void dgvDomian_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
        {
            
            if (dgvDomian.AllowUserToDeleteRows)
            {
                for (int i = 0; i < domains.domList.Count; i++)
                {
                    if (((Domain)domains.domList[i]).Row == e.Row)
                    {
                        domains.domList.RemoveAt(i);
                    }
                }
                for (int i = 0; i <domains.valList.Count; i++)
                {
                    if (((Value)domains.valList[i]).domainRow == e.Row)
                    {
                        domains.valList.RemoveAt(i);
                    }
                }
            }
        }

        private void dgvValue_CellValidated(object sender, DataGridViewCellEventArgs e)
        {
            if (!CodeChange)
            {
                DataGridView sender_ = (DataGridView) sender;
                // проверим на главный баг
                if (dgvValue[e.ColumnIndex, e.RowIndex].Value == null && OldValue != null)
                {
                    dgvValue.CurrentCell.Value = OldValue;
                    tsslDom.BackColor = Color.Blue;
                    tsslDom.Text = "для удаления ячейки выделите ее и нажмите Del";
                }
                if (dgvValue[e.ColumnIndex, e.RowIndex].Value != null)
                {
                    // проверим на пустые значения
                    if (string.IsNullOrWhiteSpace(sender_[e.ColumnIndex, e.RowIndex].Value.ToString()))
                    {
                        tsslDom.BackColor = Color.Red;
                        tsslDom.Text = "Пустое значение";
                        sender_.Columns[0].Tag = e.RowIndex;
                        return;
                    }
                    for (int i = 0; i < sender_.RowCount - 1; i++)
                    {
                        if (sender_[e.ColumnIndex, i].Value != null)
                        {
                            if (sender_[e.ColumnIndex, e.RowIndex].Value.ToString() ==
                                sender_[e.ColumnIndex, i].Value.ToString() && e.RowIndex != i)
                            {
                                if (OldValue != null)
                                {
                                    dgvValue[e.ColumnIndex, e.RowIndex].Value = OldValue;
                                }
                                tsslDom.BackColor = Color.Red;
                                tsslDom.Text = "Повторяющиеся значения";

                                sender_.Columns[0].Tag = e.RowIndex;
                                return;
                            }
                        }
                    }
                    //если попали сюда значить все нормально
                    bool existVal = false;
                    foreach (Value value in domains.valList)
                    {
                        if (value.Row == sender_.CurrentRow && value.domainRow == dgvDomian.CurrentRow)
                        {
                            existVal = true;


                        }
                    }
                    if (!existVal)
                    {
                        var value = new Value {Row = sender_.CurrentRow, domainRow = dgvDomian.CurrentRow};
                        domains.valList.Add(value);
                    }
                }
            }
        }

        private void dgvValue_Enter(object sender, EventArgs e)
        {
            // надо загрузить инфу об значениях доменов
            if (dgvDomian.CurrentCell.Value != null)
            {
                CodeChange = true;
                dgvValue.ReadOnly = false;
                dgvValue.Rows.Clear();
                if (dgvDomian.CurrentCell.Value != null)
                {
                    // загружаем значения выделенного домена
                    foreach (Value value in domains.valList)
                    {
                        if (value.domainRow == dgvDomian.CurrentRow)
                        {
                            dgvValue.Rows.Add(value.Row);
                        }
                    }
                }
                CodeChange = false;
            }

        }

       

        private void dgvValue_MouseEnter(object sender, EventArgs e)
        {
            tsslDom.BackColor = Color.White;
            tsslDom.Text = "Введите в ячейки значения";
        }

        private void dgvValue_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            if (dgvValue.Rows[e.RowIndex] != null)
            {
                if (dgvValue.Rows[e.RowIndex].Cells[0].Value != null)
                {
                    OldValue = dgvValue.Rows[e.RowIndex].Cells[0].Value.ToString();
                }
                else
                {
                    OldValue = null;
                }

            }
            else
            {
                OldValue = null;
            }
        }

        private void dgvValue_SelectionChanged(object sender, EventArgs e)
        {
            //Проверить на повторение
            select_error_value();
        }
        private void select_error_value()
        {
            if (dgvValue.Columns[0].
                Tag != null)
            {
                int temp = (int)dgvValue.Columns[0].Tag;
                dgvValue.Columns[0].Tag = null;
                dgvValue.ClearSelection();
                dgvValue.CurrentCell = dgvValue[0, temp];
                dgvValue.Rows[temp].Selected = true;
                dgvValue.BeginEdit(true);
            }
        }

        private void dgvValue_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
        {
            foreach (IconNode iconNode in pf.diagram.Nodes)
            {
               
            }
            for (int i = 0; i <domains.valList.Count; i++)
            {
                
                if (((Value)domains.valList[i]).Row == e.Row)
                {
                    domains.valList.RemoveAt(i);
                }
            }
            
        }

        private void dgvValue_Validated(object sender, EventArgs e)
        {
            //Проверить на повторение
            select_error_value();
        }

        private void dgvDomian_Validated(object sender, EventArgs e)
        {
            select_error();
        }

        private void dgvDomian_KeyUp(object sender, KeyEventArgs e)
        {
            dgvDomian.AllowUserToDeleteRows = true;
        }

        private void dgvDomian_CellMouseLeave(object sender, DataGridViewCellEventArgs e)
        {
            tsslDom.BackColor = Color.White;
            tsslDom.Text = "Редактирование доменов";
        }

        private void tsbExit_Click(object sender, EventArgs e)
        {
            qqqq = true;
            this.ParentForm.Close();
            
        }

        private void dgvValue_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                if (dgvValue.CurrentCell.Value != null)
                {
                    var a = pf.diagram.Nodes;
                    foreach (IconNode node in a)
                    {
                        if (node.value == dgvValue.CurrentRow.Cells[0].Value.ToString())
                        {
                            tsslDom.Text = "Данное значение используется";
                            dgvValue.AllowUserToDeleteRows = false;
                        }
                    }

                }
            }
        }

        private void dgvValue_KeyUp(object sender, KeyEventArgs e)
        {
            dgvValue.AllowUserToDeleteRows = true;
        }

        private void tsbSave_Click(object sender, EventArgs e)
        {
            pf.domains = this.domains;


        }

        private void dgvValue_DragDrop(object sender, DragEventArgs e)
        {
            // The mouse locations are relative to the screen, so they must be 
            // converted to client coordinates.
            Point clientPoint = dgvValue.PointToClient(new Point(e.X, e.Y));
             
            // Get the row index of the item the mouse is below. 
            rowIndexOfItemUnderMouseToDrop =
                dgvValue.HitTest(clientPoint.X, clientPoint.Y).RowIndex;
            if (rowIndexOfItemUnderMouseToDrop ==-1)
            {
                return;
                
            }
            
            if (dgvValue.Rows[rowIndexOfItemUnderMouseToDrop].Cells[0].Value==null)
            {
                return;
            }
            // If the drag operation was a move then remove and insert the row.
            if (e.Effect == DragDropEffects.Move)
            {
                DataGridViewRow rowToMove = e.Data.GetData(typeof(DataGridViewRow)) as DataGridViewRow;
                dgvValue.Rows.RemoveAt(rowIndexFromMouseDown);
                dgvValue.Rows.Insert(rowIndexOfItemUnderMouseToDrop, rowToMove);

                // меняем место в списке
                // если первый то просто ставим его первым.
                
                
                foreach (Value value in domains.valList)
                {
                    if (value.Row.Cells[0].Value.ToString()==rowToMove.Cells[0].Value.ToString())
                    {
                        var count = 0;
                        foreach (Value value_ in domains.valList)
                        {
                            if (value_.domainRow == value.domainRow)
                            {
                                count++;
                            }
                            if (count == rowIndexOfItemUnderMouseToDrop+1)
                            {
                                var a = value;
                                domains.valList.Remove(value);
                                if (rowIndexOfItemUnderMouseToDrop < rowIndexFromMouseDown)
                                {
                                    domains.valList.Insert(domains.valList.IndexOf(value_), a);
                                }
                                else
                                {
                                    domains.valList.Insert(domains.valList.IndexOf(value_)+1, a);
                                }
                                
                                break;
                            }
                        }
                        break;
                    }
                }
            
                
                
            }


            //////// The mouse locations are relative to the screen, so they must be 
            //////// converted to client coordinates.
            //////Point clientPoint = dgvValue.PointToClient(new Point(e.X, e.Y));

            //////// Get the row index of the item the mouse is below. 
            //////rowIndexOfItemUnderMouseToDrop =
            //////    dgvValue.HitTest(clientPoint.X, clientPoint.Y).RowIndex;

            //////// If the drag operation was a move then remove and insert the row.

            //////if (e.Effect == DragDropEffects.Move)
            //////{
            //////    if ((rowIndexOfItemUnderMouseToDrop != dgvValue.Rows.Count - 1) && rowIndexOfItemUnderMouseToDrop != -1 &&
            //////       rowIndexFromMouseDown != dgvValue.Rows.Count - 1 && rowIndexFromMouseDown != rowIndexOfItemUnderMouseToDrop)
            //////    {


            //////        DataGridViewRow rowToMove = e.Data.GetData(
            //////            typeof(DataGridViewRow)) as DataGridViewRow;

            //////        dgvValue.Rows.RemoveAt(rowIndexFromMouseDown);
            //////        dgvValue.Rows.Insert(rowIndexOfItemUnderMouseToDrop, rowToMove);
            //////        dgvValue.ClearSelection();
            //////        dgvValue.Rows[rowIndexOfItemUnderMouseToDrop].Selected = true;

            //////        dgvValue.BeginEdit(false);
            //////    }
            //////}
        }

        private void dgvValue_DragOver(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
            //e.Effect = DragDropEffects.Move;
            //if (e.Y <= PointToScreen(new Point(dgvValue.Location.X, dgvValue.Location.Y)).Y + 40 && dgvValue.FirstDisplayedScrollingRowIndex > 1)
            //    dgvValue.FirstDisplayedScrollingRowIndex -= 1;
            //if (dgvValue.FirstDisplayedScrollingRowIndex < dgvValue.Rows.Count - 1 && e.Y >= PointToScreen(new Point(dgvValue.Location.X +
            //   dgvValue.Width, dgvValue.Location.Y +
            //   dgvValue.Height)).Y - 10)
            //    dgvValue.FirstDisplayedScrollingRowIndex += 1;
        }

        private void dgvValue_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
        {
            ////if ((e.Button & MouseButtons.Left) == MouseButtons.Left /*&& tsslDom.BackColor != Color.Red*/)
            ////{
            ////    // If the mouse moves outside the rectangle, start the drag.
            ////    if (dragBoxFromMouseDown != Rectangle.Empty &&
            ////        !dragBoxFromMouseDown.Contains(e.X, e.Y))
            ////    {

            ////        // Proceed with the drag and drop, passing in the list item.                    
            ////        DragDropEffects dropEffect = dgvValue.DoDragDrop(
            ////        dgvValue.Rows[rowIndexFromMouseDown],
            ////        DragDropEffects.Move);
            ////    }
            ////}
        }

        private void dgvValue_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
           /* // Get the index of the item the mouse is below.
            rowIndexFromMouseDown = dgvValue.HitTest(e.X, e.Y).RowIndex;

            if (rowIndexFromMouseDown != -1 && dgvValue.Rows[rowIndexFromMouseDown].Cells[0].Value != null && dgvValue.Rows[rowIndexFromMouseDown].Cells[1].Value != null && dgvValue.Tag == null)
            {

                // Remember the point where the mouse down occurred. 
                // The DragSize indicates the size that the mouse can move 
                // before a drag event should be started.                
                Size dragSize = SystemInformation.DragSize;

                // Create a rectangle using the DragSize, with the mouse position being
                // at the center of the rectangle.
                dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2),
                                                               e.Y - (dragSize.Height / 2)),
                                    dragSize);
            }
            else
                // Reset the rectangle if the mouse is not over an item in the ListBox.
                dragBoxFromMouseDown = Rectangle.Empty;*/
        }

        private void dgvValue_MouseMove(object sender, MouseEventArgs e)
        {
            if (((e.Button & MouseButtons.Left) == MouseButtons.Left) && dgvValue.CurrentCell.Value!=null)
            {
                // If the mouse moves outside the rectangle, start the drag.
                if (dragBoxFromMouseDown != Rectangle.Empty && !dragBoxFromMouseDown.Contains(e.X, e.Y))
                {

                    // Proceed with the drag and drop, passing in the list item.                    
                    DragDropEffects dropEffect = dgvValue.DoDragDrop(dgvValue.Rows[rowIndexFromMouseDown],DragDropEffects.Move);
                }
            }

        }

        private void dgvValue_MouseDown(object sender, MouseEventArgs e)
        {
            // Get the index of the item the mouse is below.
            rowIndexFromMouseDown = dgvValue.HitTest(e.X, e.Y).RowIndex;

            if (rowIndexFromMouseDown != -1)
            {
                // Remember the point where the mouse down occurred. 
                // The DragSize indicates the size that the mouse can move 
                // before a drag event should be started.                
                Size dragSize = SystemInformation.DragSize;

                // Create a rectangle using the DragSize, with the mouse position being
                // at the center of the rectangle.
                dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2),
                                                               e.Y - (dragSize.Height / 2)),
                                    dragSize);
            }
            else
                // Reset the rectangle if the mouse is not over an item in the ListBox.
                dragBoxFromMouseDown = Rectangle.Empty;

        }
    }
}

